package com.itboye.sunsunhome.volley;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Spanned;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.Listener;
import com.android.volley.ServerError;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.itboye.sunsunhome.bean.MessagExtraBean;
import com.itboye.sunsunhome.util.DataEncryptionUtil;
import com.itboye.sunsunhome.util.NetPublicConstant;
import com.itboye.sunsunhome.util.String2Spanned;
import com.itboye.sunsunhome.www.aq.base.MyApplication;


/**
 * 建造者模式创建Request  
 * .默认请求 DEPRECATED_GET_OR_POST
 * 
 * @author Young
 *
 * @param <T> 请求结束后返回的对象，可以是 List<自定义类>  或  自定义类  
 */
public class XJsonRequest<T> extends Request<T> {

	private Listener<T> listener;

	private XErrorListener errorListener;
	private Map<String,String>headers=new HashMap<String, String>();
	private  int method=Method.DEPRECATED_GET_OR_POST;
	private Map<String,String>params=new HashMap<String, String>();
	
	/**
	 * 处理code！=0时的特殊情况！！！！！！
	 * 
	 */
	private boolean isCodeZero=true;
	/**
	 * 
	 * 
	 * @param method
	 * @param url
	 * @param listener
	 * @param errlistener  请求异常，失败，code！=0 时会调用，</br></br>
	 * code!=0时，onErrorResponse(Exception exception,int code,String msg)中
	 * exception 是CodeErrorException，code为服务器返回的状态码，msg为服务端返回的出错信息（data中字符串）
	 * </br></br>
	 * json解析失败时，onErrorResponse(Exception exception,int code,String msg)中
	 * exception 是JSONException，code为0，msg为null
	 * </br></br>
	 * 其他异常时 onErrorResponse(Exception exception,int code,String msg)中
	 * exception 是Exception，code为0，msg为null
	 */
	public XJsonRequest(String url, XRequestListener<T> listener, XErrorListener errlistener) {
		
		super(Method.DEPRECATED_GET_OR_POST,url, null);
		this.listener = listener;
		this.errorListener=errlistener;
	}
	
	/**
	 * 
	 * @param method
	 * @param url
	 * @param listener
	 * @param errlistener  请求异常，失败，code！=0 时会调用，</br></br>
	 * code!=0时，onErrorResponse(Exception exception,int code,String msg)中
	 * exception 是CodeErrorException，code为服务器返回的状态码，msg为服务端返回的出错信息（data中字符串）
	 * </br></br>
	 * json解析失败时，onErrorResponse(Exception exception,int code,String msg)中
	 * exception 是JSONException，code为0，msg为null
	 * </br></br>
	 * 其他异常时 onErrorResponse(Exception exception,int code,String msg)中
	 * exception 是Exception，code为0，msg为null
	 */
	public XJsonRequest(int method,String url, XRequestListener<T> listener, XErrorListener errlistener) {
		
		super(method, url, null);
		
		this.listener = listener;
		this.errorListener=errlistener;
	}

	
	@Override
	protected void deliverResponse(T response) {
		if (null != listener) {
			try {
				listener.onResponse(response);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public void deliverError(VolleyError error) {
		super.deliverError(error);
//		DebugToast.show("deliverError\n"+error.toString(), 1);
		if (errorListener!=null&& isCodeZero) { 
			try {
				errorListener.onErrorResponse(error, 0, null);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if ( error instanceof AuthFailureError ||
				error instanceof NetworkError ||
				error instanceof ServerError||
				error instanceof TimeoutError||
				error instanceof ParseError
				) {
			Toast.makeText(MyApplication.context, "出错了", 0).show();
		} 
		
		System.out.println("volleyerr-->"+params.get(NetPublicConstant.Type_Key)+":\n"+ error);
	}
	public XJsonRequest<T>addHeader(String k,String value){
		headers.put(k, value);
		return this;
	}
	@Override
	public Map<String, String> getHeaders() throws AuthFailureError {
		return  headers;
	}
	
	public XJsonRequest<T>setMethod(int method){
		this.method=method;
		return this;
	}
	@Override
	public int getMethod() {
		return  method;
	}
	
	public XJsonRequest<T>addParam(String k,String value){
		params.put(k, value);
		return this;
	}
	public XJsonRequest<T>addParams(Map<String,String>params){
		this.params.putAll(params);
		return this;
	}
	@Override
	protected Map<String, String> getParams() throws AuthFailureError {
		System.out.println("requestParams"+params.get(NetPublicConstant.Type_Key)+":\n"+params.toString());
		return  params;
	}
	
	
	//该方法中gson解析可能需要调整
	@Override
	protected Response<T> parseNetworkResponse(NetworkResponse response) {
		String parsed;
		try {
			parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
		} catch (UnsupportedEncodingException e) {
			parsed = new String(response.data);
		}

		System.out.println("rawResponse"+"-->"+params.get(NetPublicConstant.Type_Key)+":\n"+parsed);
		if (listener != null) {
			Type typeClass1 = listener.getClass().getGenericSuperclass();
			if (typeClass1 instanceof ParameterizedType) {
				Type actualType1 = ((ParameterizedType) typeClass1).getActualTypeArguments()[0];

				//System.out.println("type==="+actualType1);
//				Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
//				T res = gson.fromJson(parsed, actualType1);
				
				JSONObject jsonObject;
				try {
					jsonObject = new JSONObject(parsed);
					String resultData = jsonObject.getString("data");
					
					 parsed = DataEncryptionUtil.decodeData(resultData);
					 System.out.println("数据来了"+parsed);
					System.out.println("decodeRespo-->"+params.get(NetPublicConstant.Type_Key) );
					jsonObject = new JSONObject(parsed);
					int code = jsonObject.getInt("code");
					if (code!=0) {
						if (errorListener!=null) {
							
							handlerError(new CodeErrorException("error , code != 0 !!!"), code, jsonObject.getString("data"));
						}
						return null;
					}
					 resultData = jsonObject.getString("data");
					 Gson gson = new GsonBuilder()
							 .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
							 .registerTypeAdapter(Spanned.class, new String2Spanned())
							 .registerTypeAdapter(MessagExtraBean.class, new MessageExtra())
							 .create();
					T res = gson.fromJson(resultData, actualType1);

					if (null!=res) {
						return Response.success(res, HttpHeaderParser.parseCacheHeaders(response));
					}/*else{
						throw new JSONException("gson parse error ！");
					}*/
					
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
//					if (errorListener!=null) {
//						 
//						handlerError(e, 0, null);
//					}
					return null;
				}
				

			}
		}
//		if (errorListener!=null) {
//			 
//			handlerError(new Exception("may be XRequestListener == null !  or  泛型参数缺失"), 0, null);
//		}
		return null;

	}
//	private void printFullOrigResponse(String json) {
//		// TODO Auto-generated method stub
//		if (Debug.isDebug==false) {
//			return;
//		}
//		try {
//			System.out.println("decodeRespOrig","-->"+params.get(NetPublicConstant.Type_Key) );
//			int len=3500;
//			int position=0;
//			
//			while(json.length()-position>len){
//			 
//				System.out.println("decodeRespOrig",json.substring(position, position+len));
//
//				position=position+len+1;
//				 
//				
//			}
//			 
//			System.out.println("decodeRespOrig", json.substring(position, json.length()));
//		} catch (Exception e) {
//			// TODO: handle exception
//		}
//		
//	}

	/**
	 * 输出完整json，防止一次输出过多时显示不完整问题
	 * @param tag
	 * @param json
	 */
//	protected static void printLogDetail(String tag, String json) {
//		if (Debug.isDebug==false) {
//			return;
//		}
//		try {
//			int len=3500;
//			int position=0;
//			
//			while(json.length()-position>len){
//				for (int i = 0; i < json.length()-position-len; i++) {
//					if (json.charAt(position+len+i)=='\n') {
//						System.out.println(tag, json.substring( position,position+len+i ));
//
//						position=position+len+i+1;
//						break;
//					}
//				}
//				
//			}
//			System.out.println(tag, json.substring( position,json.length()));
//
//		} catch (Exception e) {
//			System.out.println(tag, json);
//		}
//		
//	}

	private void handlerError(final Exception exception,final int code,final String msg){
		isCodeZero=false;
		new Handler(Looper.getMainLooper()){
			@Override
			public void handleMessage(Message m) {
				// TODO Auto-generated method stub
				super.handleMessage(m);
				try {
					errorListener.onErrorResponse(exception, code, msg);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}.sendEmptyMessage(0);
		System.out.println("volleyerr"+params.get(NetPublicConstant.Type_Key)+":\n"+exception);
	}

}
